package com.winchain.chainbill.tbill.biz.service.impl;

import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.cfca.CfcaConfiguration;
import com.shell.bee.entity.mvc.RetMsg;
import com.shell.bee.persistence.annotation.Pagination;
import com.shell.bee.persistence.model.PageLimit;
import com.shell.framework.utils.CommonDataUtil;
import com.winchain.chainbill.basic.context.TimeoutOperation;
import com.winchain.chainbill.basic.invoice.rx.TBillInvoiceDfrUploadUpdateSubscriber;
import com.winchain.chainbill.serfee.rx.TBillDctUpdateSerFeeSubscriber;
import com.winchain.chainbill.tbill.base.dao.TbRecDao;
import com.winchain.chainbill.tbill.base.po.TbDct;
import com.winchain.chainbill.tbill.base.po.TbOpt;
import com.winchain.chainbill.tbill.base.po.TbRec;
import com.winchain.chainbill.tbill.base.service.TbDctService;
import com.winchain.chainbill.tbill.base.service.TbRecService;
import com.winchain.chainbill.tbill.basic.rx.TBillMoveSubscriber;
import com.winchain.chainbill.tbill.basic.rx.TBillOptSubscriber;
import com.winchain.chainbill.tbill.basic.service.TBillTimeoutService;
import com.winchain.chainbill.tbill.biz.TBill;
import com.winchain.chainbill.tbill.biz.TBillEvent;
import com.winchain.chainbill.tbill.biz.rx.TBillArtisanProtoSignSubscriber;
import com.winchain.chainbill.tbill.biz.rx.TBillDctAprvDeductInsSubscriber;
import com.winchain.chainbill.tbill.biz.rx.TBillDctAprvMsgSubscriber;
import com.winchain.chainbill.tbill.biz.rx.TBillDctDebitProtoSignSubscriber;
import com.winchain.chainbill.tbill.biz.rx.TBillDctProtoSignSubscriber;
import com.winchain.chainbill.tbill.biz.rx.TBillDctQuotaSubscriber;
import com.winchain.chainbill.tbill.biz.rx.TBillDctSubscriber;
import com.winchain.chainbill.tbill.biz.rx.TBillRjctUpdateAttSubscriber;
import com.winchain.chainbill.tbill.biz.rx.TBillSaveSerFeeDebitDetailListSubcriber;
import com.winchain.chainbill.tbill.biz.service.TBillAprvService;
import com.winchain.chainbill.tbill.biz.vo.TbRecVo;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import rx.Observable;

@Service
public class TBillAprvServiceImpl
  implements TBillAprvService
{
  @Autowired
  private TbRecDao tbRecDao;
  @Autowired
  private TbDctService tbDctService;
  @Autowired
  private TbRecService tbRecService;
  @Autowired
  private TBillOptSubscriber tBillOptSubscriber;
  @Autowired
  private TBillMoveSubscriber tBillMoveSubscriber;
  @Autowired
  private TBillDctSubscriber tBillDctSubscriber;
  @Autowired
  private TBillDctAprvMsgSubscriber tBillDctAprvMsgSubscriber;
  @Autowired
  private TBillDctAprvDeductInsSubscriber tBillDctAprvDeductInsSubscriber;
  @Autowired
  private TBillDctQuotaSubscriber tBillDctQuotaSubscriber;
  @Autowired
  private TBillDctUpdateSerFeeSubscriber tBillDctUpdateSerFeeSubscriber;
  @Autowired
  private TBillDctProtoSignSubscriber tBillDctProtoSignSubscriber;
  @Autowired
  private TBillTimeoutService tBillTimeoutService;
  @Autowired
  private TBillArtisanProtoSignSubscriber tBillArtisanProtoSignSubscriber;
  @Autowired
  private TBillRjctUpdateAttSubscriber tBillRjctUpdateAttSubscriber;
  @Autowired
  private TBillInvoiceDfrUploadUpdateSubscriber tBillInvoiceDfrUploadUpdateSubscriber;
  @Autowired
  private TBillDctDebitProtoSignSubscriber tBillDctDebitProtoSignSubscriber;
  @Autowired
  private TBillSaveSerFeeDebitDetailListSubcriber tBillSaveSerFeeDebitDetailListSubcriber;
  
  @Pagination
  public List<TbRecVo> queryAprvList(PageLimit limit, String cusName, String billCode)
  {
    String billState = "S002";
    if (StringUtil.notEmpty(cusName)) {
      cusName = StringUtil.getParameterLike(cusName);
    }
    if (StringUtil.notEmpty(billCode)) {
      billCode = StringUtil.getParameterLike(billCode);
    }
    String finId = CommonDataUtil.getCurEntId();
    return this.tbRecDao.queryAprvList(billState, cusName, finId, billCode);
  }
  
  public RetMsg pass(String dctId, String location, String phoneCode)
  {
    TbDct dct = (TbDct)this.tbDctService.selectByKey(dctId);
    TbRec rec = (TbRec)this.tbRecService.selectByKey(dct.getBillId());
    TbOpt opt = getOpt(rec);
    opt.setOptCode("E004");
    opt.setRemark("������������");
    
    String timeOutMsg = "��������,������������";
    TimeoutOperation timeoutOpt = new TimeoutOperation();
    timeoutOpt.setOptCode("E006");
    timeoutOpt.setRemark(timeOutMsg);
    boolean timeOut = this.tBillTimeoutService.check(rec, opt, timeoutOpt);
    if (timeOut)
    {
      reject(rec, dct, opt);
      return new RetMsg("warning", false, timeOutMsg);
    }
    TBill<TbDct> bill = new TBill();
    bill.setSource(dct);
    bill.setRec(rec);
    TBillEvent<TbDct> event = new TBillEvent(bill);
    event.setOperation(opt);
    event.setValue("quotaOptType", "tb_use");
    event.setValue("serFeeBizState", "0");
    event.setValue("phoneCode", phoneCode);
    event.setValue("location", location);
    event.setValue("sealCode", CfcaConfiguration.getCfcaBankSealCode());
    event.setValue("zySealCode", CfcaConfiguration.getCfcaZySealCode());
    Observable<TBillEvent<TbDct>> observers = Observable.just(event);
    
    observers.subscribe(this.tBillDctProtoSignSubscriber);
    observers.subscribe(this.tBillArtisanProtoSignSubscriber);
    event.setValue("zySignDebitProto", "1");
    observers.subscribe(this.tBillDctDebitProtoSignSubscriber);
    event.setValue("zySignDebitProto", "0");
    observers.subscribe(this.tBillDctDebitProtoSignSubscriber);
    observers.subscribe(this.tBillSaveSerFeeDebitDetailListSubcriber);
    observers.subscribe(this.tBillOptSubscriber);
    observers.subscribe(this.tBillMoveSubscriber);
    observers.subscribe(this.tBillDctSubscriber);
    observers.subscribe(this.tBillDctQuotaSubscriber);
    observers.subscribe(this.tBillDctUpdateSerFeeSubscriber);
    observers.subscribe(this.tBillDctAprvDeductInsSubscriber);
    observers.subscribe(this.tBillDctAprvMsgSubscriber);
    return new RetMsg("success", false, "��������������");
  }
  
  private void reject(TbRec rec, TbDct dct, TbOpt opt)
  {
    dct.setDctState("0");
    TBill<TbDct> bill = new TBill();
    bill.setSource(dct);
    bill.setRec(rec);
    TBillEvent<TbDct> event = new TBillEvent(bill);
    event.setOperation(opt);
    event.setValue("quotaOptType", "qt_ubk");
    event.setValue("serFeeBizState", "D");
    event.setValue("dfrState", "D");
    Observable<TBillEvent<TbDct>> observers = Observable.just(event);
    observers.subscribe(this.tBillOptSubscriber);
    observers.subscribe(this.tBillMoveSubscriber);
    observers.subscribe(this.tBillDctSubscriber);
    observers.subscribe(this.tBillDctQuotaSubscriber);
    observers.subscribe(this.tBillDctUpdateSerFeeSubscriber);
    observers.subscribe(this.tBillRjctUpdateAttSubscriber);
    observers.subscribe(this.tBillInvoiceDfrUploadUpdateSubscriber);
    observers.subscribe(this.tBillDctAprvMsgSubscriber);
  }
  
  private TbOpt getOpt(TbRec rec)
  {
    TbOpt opt = new TbOpt();
    opt.setCurState(rec.getBillState());
    opt.setLimDate(rec.getExpDate());
    return opt;
  }
  
  public RetMsg reject(String dctId, String remark)
  {
    TbDct dct = (TbDct)this.tbDctService.selectByKey(dctId);
    TbRec rec = (TbRec)this.tbRecService.selectByKey(dct.getBillId());
    TbOpt opt = getOpt(rec);
    opt.setOptCode("E005");
    opt.setRemark(remark);
    reject(rec, dct, opt);
    return new RetMsg("success", false, "����������");
  }
  
  public int getMsgCountForTBillAprv(String cusId)
  {
    String billState = "S002";
    return this.tbRecDao.getMsgCountForTBillAprv(billState, cusId);
  }
}
